package ru.greeneyes.socksThrough;

import java.util.List;
import java.util.ArrayList;

import org.apache.commons.cli.Options;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.CommandLine;

/**
 * @author ivanalx
 * @date 20.05.2009 14:18:51
 */
public class Starter {
	public static final String DESCR_BANNER = "Small java program for allowing your application to go through socks proxy with out any socks proxy support on your side.\n"
			+ "Your should specify binding host and port, socks proxy host and port and target service host and port for this application."
			+ "And change connection settings to target service in your application to localy binded host and port (from local-host and local-port params).";
	public static final String HELP_WITH_PARAMTH_BANNER = "java -jar throughProxy.jar "
			+ "[--local-host=HOST_FOR_CONNECTION_WAITING] "
			+ "--local-port=PORT_FOR_CONNECTION_WAITING"
			+ "--proxy-port=PORT_OF_SOCKS_PROXY "
			+ "--proxy-host=HOST_OF_SOCKS_PROXY "
			+ "--target-host=HOST_OF_TARGET_SERVICE "
			+ "--target-port=PORT_OF_TARGET_SERVICE ";

	public static void main(String[] args) {
		Options options = new Options();
		options.addOption("help", "help", false, "Help");
		options.addOption("pport", "proxy-port", true, "Port of socks proxy");
		options.addOption("phost", "proxy-host", true, "Host of socks proxy");
		options.addOption("tport", "target-port", true, "Port of socks target service");
		options.addOption("thost", "target-host", true, "Host of socks target service");
		options.addOption("lport", "local-port", true, "Local port for binding");
		options.addOption("lhost", "local-host", true, "Local host for binding, if not specified, application bind to all interafaces");

		CommandLineParser parser = new GnuParser();
		CommandLine cm = null;
		try {
			cm = parser.parse(options, args);
		} catch (ParseException e) {
			System.err.println("An error found while comman line parcing: " + e.getMessage());
			System.out.println(HELP_WITH_PARAMTH_BANNER);
			System.exit(1);
		}

		if (cm.hasOption("help")) {
			System.out.println(DESCR_BANNER);
			System.out.println("Usages:");
			System.out.println(HELP_WITH_PARAMTH_BANNER);
			System.exit(0);
		}
		SocksProperties properties = new SocksProperties();
		properties.setLocalHost(cm.getOptionValue("lhost", null));
		properties.setLocalPort(Integer.valueOf(cm.getOptionValue("lport", "-1")));

		properties.setSocksProxyHost(cm.getOptionValue("phost", null));
		properties.setSocksProxyPort(Integer.valueOf(cm.getOptionValue("pport", "-1")));

		properties.setTargetHost(cm.getOptionValue("thost", null));
		properties.setTargetPort(Integer.valueOf(cm.getOptionValue("tport", "-1")));

		List<String> errors = new ArrayList<String>();
		if (properties.getLocalPort() == -1 || properties.getLocalPort() > 65535) {
			errors.add("You need to specify local port for binding or fill it with right value");
		}
		if (properties.getSocksProxyPort() == -1 || properties.getSocksProxyPort() > 65535) {
			errors.add("You need to specify socks proxy port for binding or fill it with right value");
		}
		if (properties.getTargetPort() == -1 || properties.getTargetPort() > 65535) {
			errors.add("You need to specify target port for binding or fill it with right value");
		}
		if (properties.getSocksProxyHost() == null || "".equals(properties.getSocksProxyHost().trim())) {
			errors.add("You need to specify socks proxy host for binding or fill it with right value");
		}

		if (properties.getTargetHost() == null || "".equals(properties.getTargetHost().trim())) {
			errors.add("You need to specify target host for binding or fill it with right value");
		}

		if (errors.size() > 0) {
			System.err.println("Errors are:");
			for (String s : errors) {
				System.err.println(s);
			}
			System.err.println(HELP_WITH_PARAMTH_BANNER);
			System.exit(2);
		}
		ProxyThrower proxyThrower = new ProxyThrower(properties);
		proxyThrower.run();
	}
}
